﻿using BW.WMS.WareHouseAllot.Dto.GoodsType;
using BW.WMS.WareHouseAllot.Interface.Doccode;
using BW.WMS.WareHouseAllot.Interface.GoodsType;
using BW.WMS.WareHouseAllot.Parameter.Input.GoodsType;
using BW.WMS.WareHouseAllot.Parameter.Output.GoodsType;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.ObjectMapping;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;


namespace BW.WMS.WareHouseAllot.GoodsType
{
    /// <summary>
    /// 货品类型服务类
    /// </summary>
    public class GoodsTypeService : ApplicationService, IGoodsTypeService, ITransientDependency
    {
        private readonly IDistributedEventBus distributedEventBus;
        private readonly IDoccodeService doccodeService;
        private readonly IRepository<GoodsTypeModel, Guid> goodsTypeRepository;

        public GoodsTypeService(IRepository<GoodsTypeModel, Guid> GoodsTypeRepository, IDistributedEventBus distributedEventBus,IDoccodeService doccodeService)
        {
            goodsTypeRepository = GoodsTypeRepository;
            this.distributedEventBus = distributedEventBus;
            this.doccodeService = doccodeService;
        }

        /// <summary>
        /// 添加货品类型
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<GoodsTypeDto> CreateGoodsType(AddGoodsTypeInput input)
        {
            var goodsType = ObjectMapper.Map<AddGoodsTypeInput, GoodsTypeModel>(input);
            ////编号等于 GT + 当前时间的年月日 +从0000开始递增的数字
            goodsType.GoodsTypeCode = "GT" + DateTime.Now.ToString("yyyyMMdd") + (await goodsTypeRepository.GetCountAsync()).ToString("D4");
            //goodsType.GoodsTypeCode = await doccodeService.GenerateCodeAsync("货品类型");
                
            await goodsTypeRepository.InsertAsync(goodsType);
            return ObjectMapper.Map<GoodsTypeModel, GoodsTypeDto>(goodsType);

            //await distributedEventBus.PublishAsync(input);
            //return ObjectMapper.Map<AddGoodsTypeInput, GoodsTypeDto>(input);

        }

        /// <summary>
        /// 获取货品类型列表
        /// </summary>
        /// <returns></returns>
        public async Task<PagedResultDto<GoodsTypeOutput>> GetGoodsTypeTreeAsync(GoodsTypeQuertInput input)
        {
            // 1. 查询所有未删除的数据 这个你不刷新太快 我的数据库在服务器上面查询的很慢所有报这个错
            var goodsTypes = (await goodsTypeRepository.GetListAsync())
                .Where(x => !x.IsDeleted);

            // 2. 条件拼接
            if (!string.IsNullOrEmpty(input.GoodsTypeName))
            {
                goodsTypes = goodsTypes.Where(x => x.GoodsTypeName.Contains(input.GoodsTypeName));
            }
            if (!string.IsNullOrEmpty(input.GoodsTypeCode))
            {
                goodsTypes = goodsTypes.Where(x => x.GoodsTypeCode.Equals(input.GoodsTypeCode));
            }

            // 3. 排序（新增）
            goodsTypes = goodsTypes.OrderBy(x => x.Sort);

            // 4. 只递归顶级节点（优化）
            var goodsTypeList = goodsTypes.ToList();
            
            var data = ObjectMapper.Map<IEnumerable<GoodsTypeModel>, IEnumerable<GoodsTypeOutput>>(goodsTypes);
            string ids = "3fa85f64-5717-4562-b3fc-2c963f66afa6";
            Guid newid= Guid.Parse(ids);
            var datas = GetChildren(newid, goodsTypeList);


            // 5. 返回数据时不分页，直接用data.Count（修正）
            return new PagedResultDto<GoodsTypeOutput>(data.Count(), datas.ToList());
        }

        /// <summary>
        /// 递归查找子节点
        /// </summary>
        /// <param name="parentId">父级编号</param>
        /// <param name="allItems"></param>
        /// <returns></returns>
        public List<GoodsTypeOutput> GetChildren(Guid parentId, List<GoodsTypeModel> allItems)
        {
            var children = allItems
                .Where(x => x.ParentId == parentId)
                .OrderBy(x => x.Sort)
                .ToList();

            var result = ObjectMapper.Map<List<GoodsTypeModel>, List<GoodsTypeOutput>>(children);

            foreach (var child in result)
            {
                child.Children = GetChildren(child.Id, allItems);
            }
            return result;
        }

        /// <summary>
        /// 根据货品id获取货品类型信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Task<GoodsTypeOutput> GetGoodsTypeValue(Guid id)
        {
            var goodsType = goodsTypeRepository.GetAsync(id);

            if (goodsType == null)
            {
                throw new ArgumentException("货品类型不存在");
            }

            // 使用AutoMapper将实体映射为DTO
            var  data=ObjectMapper.Map<GoodsTypeModel, GoodsTypeOutput>(goodsType.Result);

            return Task.FromResult(data);
        }

        /// <summary>
        /// 修改货品类型信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<GoodsTypeDto> UpdateGoodsType(Guid id, UpdateGoodsTypeInput input)
        {
            //根据id获取货品类型
            var goodsType = await goodsTypeRepository.GetAsync(id);

            if (goodsType == null)
            {
                throw new ArgumentException("货品类型不存在");
            }
            //将输入参数映射到实体
            ObjectMapper.Map(input, goodsType);
            //更新实体
            await goodsTypeRepository.UpdateAsync(goodsType);
            return ObjectMapper.Map<GoodsTypeModel, GoodsTypeDto>(goodsType);
        }

        /// <summary>
        /// 删除货品类型信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteGoodsType(Guid id)
        {
            //根据id获取货品类型
            var goodsType = await goodsTypeRepository.GetAsync(id);
            if (goodsType == null)
            {
                throw new UserFriendlyException("货品类型不存在");
            }
            // 2. 查询是否存在子节点
            var hasChildren = await goodsTypeRepository.AnyAsync(x => x.ParentId == id && !x.IsDeleted);
            if (hasChildren)
            {
                throw new UserFriendlyException("该货品类型存在子节点，不能删除！");
            }
            goodsType.IsDeleted = true;
            await goodsTypeRepository.UpdateAsync(goodsType);
        }


    }
}
